package com.cskaoyan.javase.array._5operation._4crud;

import java.util.Arrays;
import java.util.Scanner;

/**
 * 数组元素的增删改查
 * 增删改查是Java程序员日常开发中最经常碰到的需求,也是比较简单的需求.
 * 增: create
 * 查: retrieve(检索)
 * 改: update
 * 删: delete
 *
 * 这里我们还没有学习数据库,所以我们来完成一个针对数组中元素的增删改成
 * 数组的长度是不可变的,所以规定:
 *      1.增: 是将数组中的默认值的位置进行赋值
 *      2.查: 是查询对应元素的下标
 *      3.改: 找到目标元素,修改取值
 *      4.删: 是将数组中的目标元素给赋值为默认值
 *
 * 需求:
 *      给一个String类型的数组,一个人名数组,请对该数组完成增删改查
 *      要求:
 *          人名数组中,人名是不能重复的
 *          比如不能装两个"张三"
 *
 * @since 10:05
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        String[] names = new String[6];
        names[0] = "张三";
        names[1] = "李四";
        names[2] = "王五";
        names[3] = "麻子";
        names[4] = "老六";
        names[5] = "小黑子";
        // System.out.println(Arrays.toString(names));
        printNames(names);
        Scanner sc = new Scanner(System.in);
       /* System.out.println("现在开始删除一个人名,请键盘录入一个人名:");
        String nameDelete = sc.nextLine();
        if (deleteName(names, nameDelete)) {
            System.out.println("删除成功了!");
            printNames(names);
        } else {
            System.out.println("删除失败了!目标人名不存在的!");
        }*/
        System.out.println("现在开始新增一个人名,请键盘录入一个人名:");
        String nameCreate = sc.nextLine();
        switch (createName(names, nameCreate)) {
            case 0:
                System.out.println("插入成功！");
                printNames(names);
                break;
            case 1:
                System.out.println("录入的人名已重复，插入失败！");
                break;
            case 2:
                System.out.println("数组已经满了，插入失败！");
                break;
        }

    }

    // 需求1: 完成对人名数组的打印,要求不打印null
    public static void printNames(String[] names) {
        System.out.print("当前人名数组中存在以下人名:\t");
        System.out.print("[");
        for (String name : names) {
            // 排除null元素
            if (name == null) {
                // 跳过这次循环
                continue;
            }
            System.out.print(name + ", ");
        }
        System.out.println("\b\b]");
    }

    // 需求2: 完成对人名数组的删除,该方法会传入一个目标人名,如果存在目标人名就删除它,如果不存在就给出一个返回结果
    // 删除要么成功,要么失败,像这种典型的结果具有二元性的返回值,给布尔类型就可以了
    public static boolean deleteName(String[] names, String targetName) {
        // 1.普通for遍历数组,查找目标人名
        for (int i = 0; i < names.length; i++) {
            // 最普通的解决方法 if判断一下,null元素全部跳过
            /*if (names[i] == null) {
                continue;
            }*/
            // 字符串如何判断是内容相同的?
            // targetName是不会为null的,将它放在左边,避免空指针异常
            if (targetName.equals(names[i])) {
                // 找到了目标人名字符串,删除它
                names[i] = null;
                return true;
            }
        }
        // 2.找到了,就赋值为null,并返回true表示删除成功
        // 3.没有找到,就返回false,表示删除失败
        return false;
    }

    // 需求3: 完成对人名数组的新增操作,注意数组中不允许出现重复的人名
    /*
        分析这个新增的方法可能的结果:
            1.录入人名成功了
            2.录入失败了,人名重复了
            3.录入失败了,数组已经满了
         这种有三个结果的方法,可以考虑返回一个状态码表示不同的结果
         规定,方法返回:
            0 --> 表示录入成功
            1 --> 表示人名重复,录入失败
            2 --> 表示数组满了,录入失败
     */
    public static int createName(String[] names, String targetName) {
        // 1.判断传入的人名是否重复
        for (String name : names) {
            if (targetName.equals(name)) {
                // 重复了,已经存在人名了,录入失败
                return 1;
            }
        }
        // 代码执行到这里,说明传入的人名肯定是不重复的
        // 2.如果不重复,开始尝试进行插入,插入成功就表示有空位
        for (int i = 0; i < names.length; i++) {
            // 尝试找到一个null位置,进行插入
            if (names[i] == null) {
                // 找到null位置,赋值,插入成功
                names[i] = targetName;
                return 0;
            }
        }
        // 代码如果执行到这里,说明人名不重复但仍插入失败了,说明数组满了
        // 3.如果插入失败,就表示没有空位
        return 2;
    }
}
